home *** CD-ROM | disk | FTP | other *** search
- /*
- * astutl.c Packet handling and misc. routines for ATARI ST kermit
- */
-
- #include <osbind.h>
- #include <stdio.h>
- #include "astinc.h"
- #include "astobj.h"
-
- extern *msg_string();
-
- /*
- * KERMIT utilities.
- */
-
-
- /*
- * s p a c k
- *
- * Send a Packet
- */
-
- spack(type,num,len,data)
- char type, *data;
- int num, len;
- {
- int i; /* Character loop counter */
- char chksum, buffer[100]; /* Checksum, packet buffer */
- register char *bufp; /* Buffer pointer */
-
- if (ibmmode)
- wait_handshake(); /* if ibm mode wait for handshake */
- if(type != 'Y' && type != 'N')
- flushinput(); /* dump any leftovers */
- len=len & 0x7f; /* Make sure len is not > 127 */
- if (len > MAXPACKSIZ ) /* Make sure not larger than buffer */
- len = MAXPACKSIZ-4; /* IF so limit it */
-
- msgdeb(MSGTLNPS,type,len,num);
- /* Display outgoing packet */
- if (data != NIL)
- data[len] = '\0'; /* Null-terminate data to print it */
- if (data != NIL)
- msgdeb(MSGDATPS,data);
-
- bufp = buffer; /* Set up buffer pointer */
-
-
- if (padding) /* Do padding */
- for (i=1; i<=spad; i++)
- Cauxout(spadc);
- if (debug && (debug > 1)) msgdeb(MSGCHPAD,spad,spadc);
-
- *bufp++ = spcks; /* Packet marker, usally SOH */
- *bufp++ = tochar(len+3); /* Send the character count */
- chksum = tochar(len+3); /* Initialize the checksum */
- *bufp++ = tochar(num); /* Packet number */
- chksum += tochar(num); /* Update checksum */
- *bufp++ = type; /* Packet type */
- chksum += type; /* Update checksum */
-
- for (i=0; i<len; i++) /* Loop for all data characters */
- {
- *bufp++ = data[i]; /* Get a character */
- chksum += data[i]; /* Update checksum */
- }
- chksum = (((chksum&0300) >> 6)+chksum)&077; /* Compute final checksum */
- *bufp++ = tochar(chksum); /* Put it in the packet */
- *bufp++ = seol; /* Extra-packet line terminator */
- *bufp = '\0';
- auxsend(buffer); /* Send the packet */
- return(TRUE);
- }
-
- /*
- * r p a c k
- *
- * Read a Packet
- */
-
- char rpack(len,num,data)
- int *len, *num; /* Packet length, number */
- char *data; /* Packet data */
- {
- int i,j, eolwc, done; /* Data character number, loop exit */
- int read_abort; /* 0 = timeout, 'A' = abort requested */
- int abort; /* restart current packet */
- char t, /* Current input character */
- type, /* Packet type */
- cchksum, /* Our (computed) checksum */
- rchksum; /* Checksum received from other host */
-
- start_timer(&startpckt);
- if (testat(&read_abort)) return(read_abort);
- do {
- if (readtimed(&t,&read_abort)) return(read_abort);
- }
- while ((t&127) != rpcks); /* Wait for packet header */
-
- done = FALSE; /* Got SOH, init loop */
- while (!done) /* Loop to get a packet */
- {
- if(readtimed(&t,&read_abort))
- return(read_abort); /* read character, or timeout */
- /* if (!image) I guess, that's nonsense! */
- t &= 0177; /* Handle parity */
- if (t == rpcks) continue; /* Resynchronize if SOH */
- cchksum = t; /* Start the checksum */
- *len = unchar(t)-3; /* Character count */
-
- if(readtimed(&t, &read_abort))
- return(read_abort); /* read character, or timeout */
- /* if (!image) nonsense ? */
- t &= 0177; /* Handle parity */
- if (t == rpcks) continue; /* Resynchronize if SOH */
- cchksum = cchksum + t; /* Update checksum */
- *num = unchar(t); /* Packet number */
-
- if(readtimed(&t, &read_abort))
- return(read_abort); /* read character, or timeout */
- /* if (!image) nonsense ? */
- t &= 0177; /* Handle parity */
- if (t == rpcks) continue; /* Resynchronize if SOH */
- cchksum = cchksum + t; /* Update checksum */
- type = t; /* Packet type */
- abort=FALSE;
-
- for (i=0; i<*len; i++) /* The data itself, if any */
- { /* Loop for character count */
- if(readtimed(&t, &read_abort))
- return(read_abort); /* read character, or timeout */
- if (!image || ebq)
- t &= 0177; /* Handle parity */
- if (t == rpcks) { /* Resynch if SOH */
- abort=TRUE;
- break;
- }
- cchksum = cchksum + t; /* Update checksum */
- data[i] = t; /* Put it in the data buffer */
- }
- if(abort)continue;
- data[*len] = 0; /* Mark the end of the data */
-
- if(readtimed(&t, &read_abort))
- return(read_abort); /* read character, or timeout */
- t &= 0177; /* do not use parity bit of checksum */
- rchksum = unchar(t); /* Convert to numeric */
- if (t == rpcks) continue; /* Resynchronize if SOH */
- done = TRUE; /* Got checksum, done */
- }
-
- if (data != NIL)
- data[*len] = '\0'; /* Null-terminate data to print it */
- msgdeb(MSGTLNPR,type,*len,*num);
- if (data != NIL)
- msgdeb(MSGDATPR,data);
-
- /* Fold in bits 7,8 to compute */
- cchksum = (((cchksum&0300) >> 6)+cchksum)&077; /* final checksum */
-
- if (cchksum != rchksum)
- {
- msgdeb(MSGCHKERR,rchksum,cchksum);
- return(FALSE);
- }
-
- /* wait for eol to avoid lost packages */
- for (eolwc=0; eolwc<100; eolwc++)
- if (Cauxis())
- break;
- else
- evnt_timer(1,0);
-
- return(type); /* All OK, return packet type */
- }
-
- /*
- * compute 'universal time'
- */
- long univ_time(t)
- int t;
- {
- long int res;
- res = 60 * ((t >> 11) & 0x1FL);
- res = 60 * (res + ((t >> 5) & 0x3FL));
- res = res + ((t & 0x1FL) << 1);
- return (res);
- }
-
- /*
- * start timer
- */
- start_timer(t0)
- long int *t0;
- {*t0 = univ_time(Tgettime());
- }
-
- /*
- * compute difference to start time
- */
- int timer(t0)
- long int t0;
- {long int t1;
- t1 = univ_time(Tgettime());
- if (t1 < t0)
- return ((int) (t1+(24*60*69)-t0));
- else
- return ((int) max((t1 - t0),1));
- }
-
-
-
- /* readtimed: read a character or timeout
- * timeout is relative to start of waiting for packet
- */
- readtimed(c,flag)
- char *c; /* character received */
- int *flag; /* flag showing reason for abort: 0=timeout,'A'=user aborted */
- {
- while(!Cauxis())
- {
- *flag = sleepwait(50);
- if (*flag == 'A') /* abort requested */
- {
- msgdeb(MSGUSRABO);
- return(TRUE);
- };
- if (state == 'W')
- start_timer(&startpckt); /* no timeout in server wait */
- if ((*flag == 'T') ||
- (stimint && dotimout && (timer(startpckt) >= stimint)))
- {
- msgdeb(MSGTIMOUT);
- timcnt += 1;
- *flag = 0;
- return(TRUE);
- };
- };
- *c = Cauxin();
- if (debug && (deblevel > 1))
- msgdeb(MSGCHRD,timer(startpckt),*c,(*c & 0x7F));
- return(FALSE);
- }
-
- /*
- * test for abort or timeout request
- */
- int testat(flag)
- int *flag;
- {
- *flag = sleepwait(0);
- if (*flag == 'A') /* abort requested */
- {
- msgdeb(MSGUSRABO);
- return(TRUE);
- };
- if (*flag == 'T')
- {
- msgdeb(MSGTIMOUT);
- timcnt += 1;
- *flag = FALSE;
- return(TRUE);
- };
- return(FALSE);
- }
-
- /*
- * b u f i l l
- *
- * Get a bufferful of data from the file that's being sent.
- * Only control-quoting is done; 8-bit & repeat count prefixes are
- * not handled. The last sentence is obsolete!
- */
-
- bufill(buffer)
- char buffer[]; /* Buffer */
- {
- int i, /* Loop index */
- t; /* Char read from file */
- char t7; /* 7-bit version of above */
- char t9; /* dup of data char t */
- char b8; /* 8th bit */
-
- i = 0; /* Init data buffer pointer */
- while(TRUE)
- {
- t = getc(fp); /* Get the next character */
- bytecnt++;
- if (feof(fp)) break;
- t9=t; /* Keep original pattern */
- t7 = t & 0177; /* Get low order 7 bits */
- b8 = t & 0200; /* Get MSB */
-
- if (ebq && b8 && image)
- buffer[i++] = ebq;
- if ((t7 < SP) || (t7==DEL) || (t7==squote)
- || ((t7 == ebq) && ebq))
- /* Does this char require */
- { /* special handling? */
- if (t=='\n' && !image)
- { /* Do LF->CRLF mapping if !image */
- buffer[i++] = squote;
- buffer[i++] = ctl('\r');
- }
- buffer[i++] = squote; /* Quote the character */
- if ((t7 != squote) && ((t7 != ebq) || !ebq))
- {
- t = ctl(t); /* and uncontrolify */
- t7 = ctl(t7);
- };
- };
- if (image && !ebq)
- buffer[i++] = t; /* Deposit the character itself */
- else
- buffer[i++] = t7;
-
-
- if (i >= spsiz-8) return(i); /* Check length */
- }
- if (i==0) return(EOF); /* Wind up here only on EOF */
- return(i); /* Handle partial buffer */
- }
-
-
- /*
- * b u f e m p
- *
- * Put data from an incoming packet into a file.
- */
-
- bufemp(buffer,len)
- char buffer[]; /* Buffer */
- int len; /* Length */
- {
- int i; /* Counter */
- char t; /* Character holder */
- int b8; /* 8th bit flag */
-
- for (i=0; i<len; i++) /* Loop thru the data field */
- {
- b8 = FALSE;
- t = buffer[i]; /* Get character */
- if (ebq && image && (ebq == (t & 0177)))
- {b8 = TRUE; t = buffer[++i];
- };
- if (t == rquote) /* Control quote? */
- {
- t = buffer[++i]; /* Get the quoted character */
- if (((t & 0177) != rquote) &&
- (((t & 0177) != ebq) || !ebq))
- /* Low order bits match quote char? */
- t = ctl(t); /* No, uncontrollify it */
- };
- if (b8) t |= 0200;
- putc(t,fp);
- bytecnt++;
- };
- }
-
-
- /*
- * s p a r
- *
- * Fill the data array with my send-init parameters
- *
- */
-
- spar(data)
- char data[];
- {
- data[0] = tochar(rpsiz); /* Biggest packet I can receive */
- data[1] = tochar(rtimint); /* When I want to be timed out */
- data[2] = tochar(MYPAD); /* How much padding I need */
- data[3] = ctl(MYPCHAR); /* Padding character I want */
- data[4] = tochar(reol); /* End-Of-Line character I want */
- data[5] = squote; /* Control-Quote character I send */
- data[6] = (image ? MYEBQ : MYNOEBQ); /* 8 bit quoting */
- }
-
-
- /* r p a r
- *
- * Get the other host's send-init parameters
- *
- */
-
- rpar(data)
- char data[];
- { if((data[0]) != 0)
- spsiz = unchar(data[0]); /* Maximum send packet size */
- if (data[1] != 0)
- stimint = unchar(data[1]); /* When I should time out */
- if (data[2] != 0)
- padding = spad = unchar(data[2]); /* Number of pads to send */
- else
- padding = spad = 0;
- spadc = ctl(data[3]); /* Padding character to send */
- if ((data[4]) != 0)
- seol = unchar(data[4]); /* EOL character I must send */
- else
- seol = MYEOL;
- if (data[5] != 0)
- rquote = data[5]; /* Incoming data quote character */
- else
- rquote = MYQUOTE;
- if (!image || (data[6] == 0) || (data[6] == 'N') || (data[6] == 'Y'))
- ebq = FALSE;
- else
- ebq = data[6];
- }
-
-
- /*
- * f l u s h i n p u t
- *
- * Dump all pending input to clear stacked up NACK's.
- */
- flushinput()
- {char c;
- /* TOS Clear AUX receive buffer */
- while (Cauxis())
- {c = Cauxin();
- if (debug && (deblevel > 1))
- msgdeb(MSGCHFLU,c,(c & 0x7F));
- };
- }
-
- /*
- * send one string to the aux port
- */
- auxsend(str)
- char *str;
- {
- while (*str != '\0')
- {if (debug && (deblevel > 1)) msgdeb(MSGCHSND,*str,(*str & 0x7F));
- Cauxout(*str++);
- };
- }
-
- /*
- * wait for handshake character
- */
- wait_handshake()
- /*
- * wait for turnchar
- * if received wait another 100 msecs and if no char received return.
- * if no char received within 1000 msecs assume we missed turnchar
- * otherwise return after a maximum of 4 secs
- */
- {
- int waitc; /* wait counter */
- char c; /* last char read */
- int nochrec; /* no char received */
- long int starthw; /* start time for wait */
- waitc = 0;
- start_timer(&starthw);
- while (TRUE)
- {if (timer(starthw) >= 4) break;
- if ((waitc >= 10) && !Cauxis()) break;
- if (Cauxis())
- {waitc = 0;
- while (Cauxis())
- {c = Cauxin() & 0x7F;
- if (debug && (deblevel > 1)) msgdeb(MSGCHWHC,c,c);
- };
- };
- evnt_timer(100,0);
- if ((c == rturnchar) && !Cauxis())
- {msgdeb(MSGHNDOK);
- return(FALSE);
- };
- waitc++;
- };
- msgdeb(MEGHNDFA);
- return(FALSE);
- }
-
- /*
- * Kermit printing routines:
- *
- */
-
-
- /*
- * Print message on DEBUG file
- * First arg is object index of the KRMESSS object
- */
-
- msgdeb(fmtix, a1, a2, a3, a4, a5)
- int fmtix;
- long a1,a2,a3,a4,a5;
- {
- if (debug)
- {
- fprintf(deb,msg_string(fmtix),a1,a2,a3,a4,a5);
- putc('\n',deb);
- };
- }
-
-
-
- /*
- * Print message on LOG file
- * if first arg >= 0 then display an alert box too
- */
- msglog(alertix,fmtix,a1,a2,a3,a4,a5)
- int fmtix, alertix;
- long a1, a2, a3, a4, a5;
- {
- if (translog)
- {
- fprintf(log,msg_string(fmtix),a1,a2,a3,a4,a5);
- putc('\n',log);
- };
- if (alertix >= 0)
- displ_alert(1,alertix);
- }
-
- /*
- * Print message on DEBUG and LOG file
- * and perhaps display an alert box
- */
- msgall(alertix,fmtix,a1,a2,a3,a4,a5)
- int fmtix, alertix;
- {
- msgdeb(fmtix,a1,a2,a3,a4,a5);
- msglog(alertix,fmtix,a1,a2,a3,a4,a5);
- }
-
-
- /*
- * p r e r r p k t
- *
- * Print contents of error packet received from remote host.
- */
- prerrpkt(msg)
- char *msg;
- {
- msgall(-1,MSGERRPK,msg);
- displ_pckerr(msg);
- }